/******************************************************************************************************************
 * File:FireController.java
 * Course: 17655
 * Project: Assignment A3
 * Copyright: Copyright (c) 2009 Carnegie Mellon University
 * Versions:
 *	1.0 March 2009 - Initial rewrite of original assignment 3 (ajl).
 *
 * Description:
 *
 * This class simulates a device that controls a fire alarm. 
 * 
 * The state (on/off) is graphically displayed on the terminal in the indicator. Command messages are displayed in
 * the message window. Once a valid command is recieved a confirmation event is sent with the id of -5 and the command in
 * the command string.
 *
 * Parameters: IP address of the event manager (on command line). If blank, it is assumed that the event manager is
 * on the local machine.
 *
 ******************************************************************************************************************/
import InstrumentationPackage.*;
import EventPackage.*;

import java.util.*;

class FireController {
	public static void main(String args[]) {
		String EvtMgrIP; // Event Manager IP address
		Event Evt = null; // Event object
		EventQueue eq = null; // Message Queue
		EventManagerInterface em = null; // Interface object to the event
											// manager
		boolean FireTriggered = false; // Heater state: false == off, true == on
		int Delay = 1000; // The loop delay (2.5 seconds)
		boolean Done = false; // Loop termination flag

		// ///////////////////////////////////////////////////////////////////////////////
		// Get the IP address of the event manager
		// ///////////////////////////////////////////////////////////////////////////////

		if (args.length == 0) {
			// event manager is on the local system

			System.out
					.println("\n\nAttempting to register on the local machine...");

			try {
				// Here we create an event manager interface object. This
				// assumes
				// that the event manager is on the local machine

				em = new EventManagerInterface();
			}

			catch (Exception e) {
				System.out
						.println("Error instantiating event manager interface: "
								+ e);

			} // catch

		} else if (args.length > 1) {
			// case where ip and binding name and passed along as command line
			// args
			long beatTime = 5000;

			// Send heart beat in default time interview

			try {
				// Here we create an event manager interface object. This
				// assumes
				// that the event manager is NOT on the local machine

				em = new EventManagerInterface(args[0], args[1]);
				if (args.length > 2) {
					// Launching heartbeat
					try {
						// Here we create an heart beat event manager interface
						// object. This
						// assumes
						// that the event manager is NOT on the local machine
						EventManagerInterface hbManager = new EventManagerInterface(
								args[2], args[3]);
						EventPackage.Event evt = new Event((int) 12);
						evt.SetSenderId(em.GetMyId());
						HeartBeat.startThread(hbManager, evt, beatTime);

						if (args.length == 6) {
							String name = args[4];
							String description = args[5];
							EventPackage.Event evt2 = new Event((int) 11, name
									+ '%' + description);
							evt2.SetSenderId(em.GetMyId());
							HeartBeat.startThread(hbManager, evt2, 30000);

						}
					} catch (Exception exp) {
						System.out.println("Failed starting Heartbeat");
					}
				}

			} catch (Exception e) {
				System.out
						.println("Error instantiating event manager interface: "
								+ e);

			} // catch
		} else {

			// event manager is not on the local system

			EvtMgrIP = args[0];

			System.out.println("\n\nAttempting to register on the machine:: "
					+ EvtMgrIP);

			try {
				// Here we create an event manager interface object. This
				// assumes
				// that the event manager is NOT on the local machine

				em = new EventManagerInterface(EvtMgrIP);
			}

			catch (Exception e) {
				System.out
						.println("Error instantiating event manager interface: "
								+ e);

			} // catch

		}

		// Here we check to see if registration worked. If em is null then the
		// event manager interface was not properly created.

		if (em != null) {
			System.out.println("Registered with the event manager.");

			/*
			 * Now we create the humidity control status and message panel* We
			 * put this panel about 2/3s the way down the terminal, aligned to
			 * the left* of the terminal. The status indicators are placed
			 * directly under this panel
			 */

			float WinPosX = 0.0f; // This is the X position of the message
									// window in terms
									// of a percentage of the screen height
			float WinPosY = 0.40f; // This is the Y position of the message
									// window in terms
									// of a percentage of the screen height

			MessageWindow mw = new MessageWindow(
					"Security Controller Status Console", WinPosX, WinPosY);

			// Now we put the indicators directly under the humitity status and
			// control panel

			Indicator hi = new Indicator("Fire Alarm", mw.GetX(), mw.GetY()
					+ mw.Height());

			mw.WriteMessage("Registered with the event manager.");

			try {
				mw.WriteMessage("   Participant id: " + em.GetMyId());
				mw.WriteMessage("   Registration Time: "
						+ em.GetRegistrationTime());

			} // try

			catch (Exception e) {
				System.out.println("Error:: " + e);

			} // catch

			/********************************************************************
			 ** Here we start the main simulation loop
			 *********************************************************************/

			while (!Done) {
				try {
					eq = em.GetEventQueue();

				} // try

				catch (Exception e) {
					mw.WriteMessage("Error getting event queue::" + e);

				} // catch

				// Go through event queue
				int qlen = eq.GetSize();

				for (int i = 0; i < qlen; i++) {
					Evt = eq.GetEvent();

					mw.WriteMessage(Evt.GetMessage());

					if (Evt.GetEventId() == 8) // fire alarm
					{
						FireTriggered = true;
						mw.WriteMessage("Received fire alarm event");

					} // if

					if (Evt.GetEventId() == 9) // StopFireAlarmEvent
					{
						FireTriggered = false;
						mw.WriteMessage("Received stop fire alarm event");
						
						try {
							em.SendEvent(new Event(15, ""));
						} catch (Exception e) {
							System.out.println("Error " + e);
						}

					} // if

					// If the event ID == 99 then this is a signal that the
					// simulation
					// is to end. At this point, the loop termination flag is
					// set to
					// true and this process unregisters from the event manager.

					if (Evt.GetEventId() == 99) {
						Done = true;

						try {
							em.UnRegister();

						} // try

						catch (Exception e) {
							mw.WriteMessage("Error unregistering: " + e);

						} // catch

						mw.WriteMessage("\n\nSimulation Stopped. \n");

						// Get rid of the indicators. The message panel is left
						// for the
						// user to exit so they can see the last message posted.

						hi.dispose();

					} // if

				} // for

				// Update the lamp status

				if (FireTriggered) {
					// Set to green, humidifier is on
					hi.SetLampColorAndMessage("Fire Alarm On", 3);

				} else {

					// Set to black, humidifier is off
					hi.SetLampColorAndMessage("Fire Alarm Off", 0);

				} // if

				try {
					Thread.sleep(Delay);

				} // try

				catch (Exception e) {
					System.out.println("Sleep error:: " + e);

				} // catch

			} // while

		} else {

			System.out
					.println("Unable to register with the event manager.\n\n");

		} // if

	} // main

}